package com.huike.report.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.huike.common.core.domain.AjaxResult;
import com.huike.report.domain.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.huike.clues.domain.TbActivity;
import com.huike.clues.domain.TbAssignRecord;
import com.huike.clues.domain.TbClue;
import com.huike.clues.domain.vo.IndexStatisticsVo;
import com.huike.clues.mapper.SysDeptMapper;
import com.huike.clues.mapper.SysDictDataMapper;
import com.huike.clues.mapper.TbActivityMapper;
import com.huike.clues.mapper.TbAssignRecordMapper;
import com.huike.clues.mapper.TbClueMapper;
import com.huike.common.core.domain.entity.SysDept;
import com.huike.common.utils.SecurityUtils;
import com.huike.contract.domain.TbContract;
import com.huike.contract.mapper.TbContractMapper;
import com.huike.report.mapper.ReportMapper;
import com.huike.report.service.IReportService;

@Service
public class ReportServiceImpl implements IReportService {

    @Autowired
    private TbContractMapper contractMapper;


    @Autowired
    private SysDictDataMapper sysDictDataMapper;


    @Autowired
    private TbClueMapper clueMapper;

    @Autowired
    private TbActivityMapper activityMapper;


    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private TbAssignRecordMapper assignRecordMapper;

    @Autowired
    private ReportMapper reportMpper;


    /**
     * 渠道统计
     */
    @Override
    public List<Map<String, Object>> chanelStatistics(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data = contractMapper.chanelStatistics(beginCreateTime, endCreateTime);
        for (Map<String, Object> datum : data) {
            String subjectValue = (String) datum.get("channel");
            String lable = sysDictDataMapper.selectDictLabel("clues_item", subjectValue);
            datum.put("channel", lable);
        }
        return data;
    }

    @Override
    public List<TbContract> contractReportList(TbContract tbContract) {
        return contractMapper.selectTbContractList(tbContract);
    }


    @Override
    public List<Map<String, Object>> activityStatistics(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data = contractMapper.activityStatistics(beginCreateTime, endCreateTime);
        for (Map<String, Object> datum : data) {
            Long activityId = (Long) datum.get("activity_id");
            TbActivity tbActivity = activityMapper.selectTbActivityById(activityId);
            if (tbActivity == null) {
                datum.put("activity", "其他");
            } else {
                datum.put("activity", tbActivity.getName());
            }
        }
        return data;
    }

    /**
     * 按照部门统计销售
     *
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> deptStatisticsList(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data = contractMapper.deptStatistics(beginCreateTime, endCreateTime);
        for (Map<String, Object> datum : data) {
            Long deptId = (Long) datum.get("dept_id");
            if (deptId != null) {
                SysDept dept = deptMapper.selectDeptById(deptId);
                datum.put("deptName", dept.getDeptName());
            }
        }
        return data;
    }


    /**
     * 按照渠道统计销售
     *
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> channelStatisticsList(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data = contractMapper.channelStatistics(beginCreateTime, endCreateTime);
        for (Map<String, Object> datum : data) {
            String subjectValue = (String) datum.get("channel");
            if (subjectValue != null) {
                String lable = sysDictDataMapper.selectDictLabel("clues_item", subjectValue);
                datum.put("channel", lable);
            }
        }
        return data;
    }


    /**
     * 按照归属人统计销售
     *
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> ownerShipStatisticsList(String beginCreateTime, String endCreateTime) {
        return contractMapper.ownerShipStatistics(beginCreateTime, endCreateTime);
    }


    @Override
    public List<TbClue> cluesStatisticsList(TbClue clue) {
        return clueMapper.selectTbClueForReport(clue);
    }

    @Override
    public List<ActivityStatisticsVo> activityStatisticsList(TbActivity query) {
        query.setStatus("2");
        List<TbActivity> activities = activityMapper.selectTbActivityList(query);
        Map<String, Object> timeMap = query.getParams();
        List<ActivityStatisticsVo> list = new ArrayList<>();
        for (TbActivity activity : activities) {
            ActivityStatisticsVo dto = new ActivityStatisticsVo();
            BeanUtils.copyProperties(activity, dto);
            TbClue tbClue = new TbClue();
            tbClue.setActivityId(activity.getId());
            tbClue.setChannel(activity.getChannel());
            tbClue.setParams(timeMap);
            Map<String, Object> clueCount = clueMapper.countByActivity(tbClue);
            if (clueCount != null) {
                dto.setCluesNum(Integer.parseInt(clueCount.get("total").toString()));
                if (clueCount.get("falseClues") != null) {
                    dto.setFalseCluesNum(Integer.parseInt(clueCount.get("falseClues").toString()));
                }
                if (clueCount.get("toBusiness") != null) {
                    dto.setBusinessNum(Integer.parseInt(clueCount.get("toBusiness").toString()));
                }
            }
            TbContract tbContract = new TbContract();
            tbContract.setChannel(activity.getChannel());
            tbContract.setActivityId(activity.getId());
            tbContract.setParams(timeMap);
            Map<String, Object> contractCount = contractMapper.countByActivity(tbContract);
            if (contractCount != null) {
                dto.setCustomersNum(Integer.parseInt(contractCount.get("customersNum").toString()));
                if (contractCount.get("amount") == null) {
                    dto.setAmount(0d);
                } else {
                    dto.setAmount((Double) contractCount.get("amount"));
                }
                if (contractCount.get("cost") == null) {
                    dto.setCost(0d);
                } else {
                    dto.setCost((Double) contractCount.get("cost"));
                }

            }
            list.add(dto);
        }
        return list;
    }


    @Override
    public IndexVo getIndex(IndexStatisticsVo request) {
        Long deptId = request.getDeptId();
        TbAssignRecord tbAssignRecord = new TbAssignRecord();
        tbAssignRecord.setLatest("1");
        assignRecordMapper.selectAssignRecordList(tbAssignRecord);
        return null;
    }


    /**
     * 获取首页基本数据
     *
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public IndexBaseInfoVO getBaseInfo(String beginCreateTime, String endCreateTime) {
        //1 构建一个空的结果集对象
        IndexBaseInfoVO result = new IndexBaseInfoVO();
        //2 封装结果集属性
        // 2.1 由于查询需要用到用户名 调用工具类获取用户名
        String username = SecurityUtils.getUsername();
        // 2.2 开始查询第一个属性 线索数量
        result.setCluesNum(reportMpper.getCluesNum(beginCreateTime, endCreateTime, username));
        // 2.3 开始查询第一个属性 商机数量
        result.setBusinessNum(reportMpper.getBusinessNum(beginCreateTime, endCreateTime, username));
        // 2.4 开始查询第一个属性 合同数量
        result.setContractNum(reportMpper.getContractNum(beginCreateTime, endCreateTime, username));
        // 2.5 开始查询第一个属性 销售金额数量
        result.setSalesAmount(reportMpper.getSalesAmount(beginCreateTime, endCreateTime, username));
        //5 返回结果集对象
        return result;
    }

    //获取首页今日基础数据信息
    @Override
    public Map<String, Object> getTodayInfo() {
        //设置返回对象 map
        Map<String, Object> map = new HashMap<>();
        //获取用户名
        String username = SecurityUtils.getUsername();
        //今日线索数目    todayCluesNum
        Integer todayCluesNum = reportMpper.getTodayCluesNum(username);
        //今日商机数目    todayBusinessNum
        Integer todayBusinessNum = reportMpper.getTodayBusinessNum(username);
        //今日合同数目    todayContractNum
        Integer todayContractNum = reportMpper.getTodayContractNum(username);
        //今日销售金额    todaySalesAmount
        Integer todaySalesAmount = reportMpper.getTodaySalesAmount(username) == null ? 0 : reportMpper.getTodaySalesAmount(username).intValue();
        //封装返回数据
        map.put("todayCluesNum", todayCluesNum);
        map.put("todayBusinessNum", todayBusinessNum);
        map.put("todayContractNum", todayContractNum);
        map.put("todaySalesAmount", todaySalesAmount);

        return map;
    }

    //待办数据统计接口
    @Override
    public Map<String, Object> getTodoInfo(String beginCreateTime, String endCreateTime) {
        //设置返回对象
        Map<String, Object> map = new HashMap<>();
        //获取当前用户
        String username = SecurityUtils.getUsername();

        //tofollowedCluesNum, 待跟进线索数目
        Integer tofollowedCluesNum = reportMpper.getTofollowedCluesNum(beginCreateTime, endCreateTime, username);

        //tofollowedBusinessNum,待跟进商机数目
        Integer tofollowedBusinessNum = reportMpper.getTofollowedBusinessNum(beginCreateTime, endCreateTime, username);

        //toallocatedCluesNum,待分配线索数目
        Integer toallocatedCluesNum = reportMpper.getToallocatedCluesNum(beginCreateTime, endCreateTime, username);

        //toallocatedBusinessNum 待分配商机数目
        Integer toallocatedBusinessNum = reportMpper.getToallocatedBusinessNum(beginCreateTime, endCreateTime, username);

        //封装数据
        map.put("tofollowedCluesNum", tofollowedCluesNum);
        map.put("tofollowedBusinessNum", tofollowedBusinessNum);
        map.put("toallocatedCluesNum", toallocatedCluesNum);
        map.put("toallocatedBusinessNum", toallocatedBusinessNum);

        return map;
    }

    //统计在时间段内每个学科的报名情况，和占比，用来分析出每个学科的火热程度
    @Override
    public List<Map<String, Object>> subjectStatistics(String beginCreateTime, String endCreateTime) {
        //分组查询学科名称和统计数量
        List<Map<String, Object>> list = reportMpper.subjectStatistics(beginCreateTime, endCreateTime);

        return list;
    }

    //统计 时间(每天)  每天新增的线索  总线索
    @Override
    public AjaxResult cluesStatistics(String beginCreateTime, String endCreateTime) throws ParseException {
        AjaxResult result = new AjaxResult();
        //Map<String, Object> map = new HashMap<>();

        //找到每天的时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //格式化日期
        Date begin = sdf.parse(beginCreateTime);
        Date end = sdf.parse(endCreateTime);
        //将开始时间存入集合
        ArrayList<Date> dates = new ArrayList<>();
        // 使用给定的 begin 设置此 Calendar 的时间
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(begin);
        // 使用给定的 end 设置此 Calendar 的时间
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(end);
        // 测试此日期是否在指定日期之后
        while (end.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            dates.add(calBegin.getTime());
        }
        //将日期转换成字符串作为key
        List<String> resultTime = new ArrayList<>();
        for (Date date : dates) {
            String format = sdf.format(date);
            resultTime.add(format);
        }
        result.put("xAxis", resultTime);
        //找到每天新增的线索数量
        //查询每天的线索数量,总线索
        ArrayList<Integer> timeClueNumList = new ArrayList<>();

        for (String createTime : resultTime) {
            Integer num = reportMpper.getTimeClueNum(createTime);
            timeClueNumList.add(num);
        }
        //封装总线索
        Map<String, Object> sumClueNums = new HashMap<>();
        sumClueNums.put("name", "线索总数量");
        sumClueNums.put("data", timeClueNumList);
        //封装每天新增的线索数量, 后一天 - 前一天
        ArrayList<Integer> clueNumlist = new ArrayList<>();
        for (int i = 0; i < timeClueNumList.size(); i++) {
            if (i + 1 < timeClueNumList.size()) {
                int data = timeClueNumList.get(i + 1) - timeClueNumList.get(i);
                clueNumlist.add(data);
            } else {
                int data = timeClueNumList.get(i) - timeClueNumList.get(i - 1);
                clueNumlist.add(data);
            }
        }
        //封装数据
        Map<String, Object> dayClueNums = new HashMap<>();
        dayClueNums.put("name", "新增线索数量");
        dayClueNums.put("data", clueNumlist);
        //封装线索数据
        ArrayList<Map<String, Object>> clueNums = new ArrayList<>();
        clueNums.add(sumClueNums);
        clueNums.add(dayClueNums);

        result.put("series", clueNums);

        return result;
    }

    //统计分析--线索统计--线索转化率漏斗图
    @Override
    public Map<String, Object> getVulnerabilityMap(String beginCreateTime, String endCreateTime) {
        //准备封装数据
        AjaxResult result = new AjaxResult();
        //cluesNums		            线索数量
        Integer cluesNums = reportMpper.getAllCluesNums(beginCreateTime, endCreateTime);

        //effectiveCluesNums  	    有效线索数
        List<String> effectiveStatus = new ArrayList<>();
        effectiveStatus.add(TbClue.StatusType.UNFOLLOWED.getValue());
        effectiveStatus.add(TbClue.StatusType.FOLLOWING.getValue());
        effectiveStatus.add(TbClue.StatusType.TOBUSINESS.getValue());

        Integer effectiveCluesNums = reportMpper.effectiveCluesNums(beginCreateTime, endCreateTime, effectiveStatus);

        //businessNums		        商机数量
        Integer businessNums = reportMpper.getAllBusinessNums(beginCreateTime, endCreateTime, TbClue.StatusType.TOBUSINESS.getValue());

        //contractNums		        合同数量
        Integer contractNums = reportMpper.getContractNums(beginCreateTime, endCreateTime, TbClue.StatusType.TOCUSTOMER.getValue());

        //封装数据
        result.put("cluesNums", cluesNums);
        result.put("effectiveCluesNums", effectiveCluesNums);
        result.put("businessNums", businessNums);
        result.put("contractNums", contractNums);

        return result;
    }

    //首页--商机转化龙虎榜接口1
    @Override
    public List<Map<String, Object>> businessChangeStatistics(String beginCreateTime, String endCreateTime) {
        //准备封装数据
        List<Map<String, Object>> businesstList = new ArrayList<>();

        //查询所有用户
        List<Map<String, Object>> userList = reportMpper.getAllUser();
        for (Map<String, Object> map : userList) {
            //if (businesstList.size() == 10) {
            //    break;
            //}
            Map<String, Object> resultMap = new HashMap<>();
            map.keySet().forEach(key -> {

                if (key.equals("create_by")) {
                    String username = (String) map.get(key);
                    //根据用户名查询商机数量
                    Integer allBusiness = reportMpper.getAllBusiness(beginCreateTime, endCreateTime, username);
                    //根据用户名查询转化数量(合同)
                    Integer allContract = reportMpper.allContract(beginCreateTime, endCreateTime, username);
                    //计算转化率
                    if (allBusiness == 0 || allContract == 0) {
                        double radio = 0.00;
                        resultMap.put("radio", radio);
                    } else {
                        //保留两位小数
                        //String format = new DecimalFormat("#.00").format(1.0 * contractNum / businessNum);
                        //String format = String.format("%.2f", 1.0 * contractNum / businessNum);
                        BigDecimal bd = new BigDecimal(1.0 * allContract / allBusiness);
                        double radio = bd.setScale(2, RoundingMode.HALF_UP).doubleValue();
                        resultMap.put("radio", radio);
                    }
                    resultMap.put(key, username);
                    resultMap.put("num", allContract);
                } else {
                    Long userId = (Long) map.get(key);
                    //根据用户名查询部门
                    String deptName = reportMpper.getDeptByUserId(userId);
                    resultMap.put("deptName", deptName);
                }
            });

            businesstList.add(resultMap);
        }
        //展示10条最多的
        List<Map<String, Object>> result = extracted(businesstList);

        return result;
    }

    @Override
    public List<Map<String, Object>> salesStatistic(String beginCreateTime, String endCreateTime) {
        //准备封装数据
        List<Map<String, Object>> businesstList = new ArrayList<>();

        //查询所有用户
        List<Map<String, Object>> userList = reportMpper.getAllUser();
        for (Map<String, Object> map : userList) {
            //if (businesstList.size() == 10) {
            //    break;
            //}
            Map<String, Object> resultMap = new HashMap<>();
            map.keySet().forEach(key -> {

                if (key.equals("create_by")) {
                    String username = (String) map.get(key);
                    //根据用户名查询线索数量
                    Integer allClues = reportMpper.getAllClues(beginCreateTime, endCreateTime, username);
                    //根据用户名查询转化数量(商机)
                    Integer transferBusiness = reportMpper.getTransferBusiness(beginCreateTime, endCreateTime, username);
                    //计算转化率
                    if (allClues == 0 || transferBusiness == 0) {
                        double radio = 0.00;
                        resultMap.put("radio", radio);
                    } else {
                        //保留两位小数
                        //String format = new DecimalFormat("#.00").format(1.0 * contractNum / businessNum);
                        //String format = String.format("%.2f", 1.0 * contractNum / businessNum);
                        BigDecimal bd = new BigDecimal(1.0 * transferBusiness / allClues);
                        double radio = bd.setScale(2, RoundingMode.HALF_UP).doubleValue();
                        resultMap.put("radio", radio);
                    }
                    resultMap.put(key, username);
                    resultMap.put("num", transferBusiness);
                } else {
                    Long userId = (Long) map.get(key);
                    //根据用户名查询部门
                    String deptName = reportMpper.getDeptByUserId(userId);
                    resultMap.put("deptName", deptName);
                }
            });

            businesstList.add(resultMap);
        }
        //展示10条最多的
        List<Map<String, Object>> result = extracted(businesstList);

        return result;
    }

    // 展示10条最多的
    private List<Map<String, Object>> extracted(List<Map<String, Object>> businesstList) {
        businesstList.sort(new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                return (Integer) o2.get("num") - (Integer) o1.get("num");
            }
        });
        return businesstList.subList(0, 10);
    }

    /*  @Override
    public List<Map<String, Object>> businessChangeStatistics(String beginCreateTime, String endCreateTime) {
        //准备封装数据
        ArrayList<Map<String, Object>> businesstList = new ArrayList<>();

        // 查询用户名, 部门名
        List<Map<String, Object>> list = reportMpper.findNamesAndDept(beginCreateTime, endCreateTime);
        //获得用户名
        for (int i = 0; i < 10; i++) {
            if (list.size() < i) {
                break;
            }
            Map<String, Object> resultMap = new HashMap<>();

            Map<String, Object> map = list.get(i);
            map.keySet().forEach(key -> {
                String username = (String) map.get(key);
                if (key.equals("create_by")) {
                    // 查询转化数量(合同数量)
                    Integer contractNum = reportMpper.findContract(beginCreateTime, endCreateTime, username);
                    // 查询商机数量
                    Integer businessNum = reportMpper.findBusiness(beginCreateTime, endCreateTime, username);
                    // 计算转化率
                    if (businessNum == 0 || contractNum == 0) {
                        double radio = 0.00;
                        resultMap.put("radio", radio);
                    } else {
                        //保留两位小数
                        //String format = new DecimalFormat("#.00").format(1.0 * contractNum / businessNum);
                        //String format = String.format("%.2f", 1.0 * contractNum / businessNum);
                        BigDecimal bd = new BigDecimal(1.0 * contractNum / businessNum);
                        double radio = bd.setScale(2, RoundingMode.HALF_UP).doubleValue();
                        resultMap.put("radio", radio);
                    }
                    resultMap.put(key, username);
                    resultMap.put("num", contractNum);
                } else {
                    resultMap.put(key, username);
                }
            });
            businesstList.add(resultMap);
        }
        return businesstList;
    }*/

/*@Override
    public ArrayList<Map<String, Object>> getTodayInfo() {
        //设置返回对象 map
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        //今日线索数目    todayCluesNum
        HashMap<String, Object> todayCluesNumMap = new HashMap<>();
        todayCluesNumMap.put("todayCluesNum",reportMpper.getTodayCluesNum());
        list.add(todayCluesNumMap);

        //今日商机数目    todayBusinessNum
        HashMap<String, Object> todayBusinessNumMap = new HashMap<>();
        todayBusinessNumMap.put("todayBusinessNum",reportMpper.getTodayBusinessNum());
        list.add(todayBusinessNumMap);

        //今日合同数目    todayContractNum
        HashMap<String, Object> todayContractNumMap = new HashMap<>();
        todayContractNumMap.put("todayContractNum",reportMpper.getTodayContractNum());
        list.add(todayContractNumMap);

        //今日销售金额    todaySalesAmount
        Integer todaySalesAmount = reportMpper.getTodaySalesAmount() == null ? 0 : reportMpper.getTodaySalesAmount().intValue();
        HashMap<String, Object> todaySalesAmountMap = new HashMap<>();
        todaySalesAmountMap.put("todaySalesAmount",todaySalesAmount);
        list.add(todaySalesAmountMap);
        //封装返回数据
        return list;
    }*/
}